% Copyright 2019 by Till Tantau
%
% This file may be distributed and/or modified
%
% 1. under the LaTeX Project Public License and/or
% 2. under the GNU Free Documentation License.
%
% See the file doc/generic/pgf/licenses/LICENSE for more details.


% \section{Tutorial: Diagrams as Simple Graphs}
\section{教程：简单的图表}

% In this tutorial we have a look at how graphs and matrices can be used to typeset a diagram.

在本教程中，我们将了解如何使用图形和矩阵来排版图表。

% Ilka, who just got tenure for her professorship on Old and Lovable Programming Languages, has recently dug up a technical report entitled \emph{The Programming Language Pascal} in the dusty cellar of the library of her university. Having been created in the good old times using pens and rules, it looks like this \footnote{The shown diagram was not scanned, but rather typeset using \tikzname. The jittering lines were created using the |random steps| decoration.}:

伊卡尔（Ilka）刚刚获得她那古老而可爱的编程语言的终身教授职位，最近在她的大学图书馆满是灰尘的地窖里挖出了一份题为``编程语言帕斯卡''的技术报告。是在过去的美好时光中使用钢笔和直尺创建的，它看起来像这样 \footnote{所示的图表不是扫描出来的，而是使用\tikzname 进行排版。抖动线是使用 |random steps| 创建的。}：

{
  \tikzset{
    nonterminal/.style={
      % The shape:
      rectangle,
      % The size:
      minimum size=6mm,
      % The border:
      very thick,
      draw=red!50!black!50,         % 50% red and 50% black,
                                    % and that mixed with 50% white
      % The filling:
      top color=white,              % a shading that is white at the top...
      bottom color=red!50!black!20, % and something else at the bottom
      % Font
      font=\itshape
    },
    terminal/.style={
      % The shape:
      rounded rectangle,
      minimum size=6mm,
      % The rest
      very thick,draw=black!50,
      top color=white,bottom color=black!20,
      font=\ttfamily},
    skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}
  }
  \tikzset{terminal/.append style={text height=1.5ex,text depth=.25ex}}
  \tikzset{nonterminal/.append style={text height=1.5ex,text depth=.25ex}}
  \pgfmathsetseed{1}
\medskip
\noindent\begin{tikzpicture}[
  >=latex,thick,
  /pgf/every decoration/.style={/tikz/sharp corners},
  fuzzy/.style={decorate,decoration={random steps,segment length=0.5mm,amplitude=0.15pt}},
  minimum size=6mm,line join=round,line cap=round,
  terminal/.style={rectangle,draw,fill=white,fuzzy,rounded corners=3mm},
  nonterminal/.style={rectangle,draw,fill=white,fuzzy},
  node distance=4mm]

  \ttfamily
  \begin{scope}[start chain,
                every node/.style={on chain},
                terminal/.append style={join=by {->,shorten >=-1pt,fuzzy,decoration={post length=4pt}}},
                nonterminal/.append style={join=by {->,shorten >=-1pt,fuzzy,decoration={post length=4pt}}},
                support/.style={coordinate,join=by fuzzy}]
    \node [support]             (start)        {};
    \node [nonterminal]                        {unsigned integer};
    \node [support]             (after ui)     {};
    \node [terminal]                           {.};
    \node [support]             (after dot)    {};
    \node [terminal]                           {digit};
    \node [support]             (after digit)  {};
    \node [support]             (skip)         {};
    \node [support]             (before E)     {};
    \node [terminal]                           {E};
    \node [support]             (after E)      {};
    \node [support,xshift=5mm]  (between)      {};
    \node [support,xshift=5mm]  (before last)  {};
    \node [nonterminal]                        {unsigned integer};
    \node [support]             (after last)   {};
    \node [coordinate,join=by ->] (end)          {};
  \end{scope}
  \node (plus)  [terminal,above=of between] {+};
  \node (minus) [terminal,below=of between] {-};

  \begin{scope}[->,decoration={post length=4pt},rounded corners=2mm,every path/.style=fuzzy]
    \draw (after ui)    -- +(0,.7)  -| (skip);
    \draw (after digit) -- +(0,-.7) -| (after dot);
    \draw (before E)    -- +(0,-1.2) -| (after last);
    \draw (after E)     |- (plus);
    \draw (plus)        -| (before last);
    \draw (after E)     |- (minus);
    \draw (minus)       -| (before last);
  \end{scope}
\end{tikzpicture}
\medskip

% For her next lecture, Ilka decides to redo this diagram, but this time perhaps a bit cleaner and perhaps also bit ``cooler''.

在下一次演讲中，伊尔卡决定重做这张图，但这一次也许更干净，也可能更``酷''。

\medskip
\noindent\begin{tikzpicture}[point/.style={coordinate},>={Stealth[round]},thick,draw=black!50,
                    tip/.style={->,shorten >=1pt},every join/.style={rounded corners},
                    hv path/.style={to path={-| (\tikztotarget)}},
                    vh path/.style={to path={|- (\tikztotarget)}}]
  \matrix[column sep=4mm] {
    % First row:
    & & & & & & &  & & & & \node (plus) [terminal] {+};\\
    % Second row:
    \node (p1) [point]  {}; &    \node (ui1)   [nonterminal] {unsigned integer}; &
    \node (p2) [point]  {}; &    \node (dot)   [terminal]    {.};                &
    \node (p3) [point]  {}; &    \node (digit) [terminal]    {digit};            &
    \node (p4) [point]  {}; &    \node (p5)    [point]  {};                      &
    \node (p6) [point]  {}; &    \node (e)     [terminal]    {E};                &
    \node (p7) [point]  {}; &                                                    &
    \node (p8) [point]  {}; &    \node (ui2)   [nonterminal] {unsigned integer}; &
    \node (p9) [point]  {}; &    \node (p10)   [point]       {};\\
    % Third row:
    & & & & & & &  & & & & \node (minus)[terminal] {-};\\
  };

  { [start chain]
    \chainin (p1);
    \chainin (ui1)   [join=by tip];
    \chainin (p2)    [join];
    \chainin (dot)   [join=by tip];
    \chainin (p3)    [join];
    \chainin (digit) [join=by tip];
    \chainin (p4)    [join];
    { [start branch=digit loop]
      \chainin (p3) [join=by {skip loop=-6mm,tip}];
    }
    \chainin (p5)    [join,join=with p2 by {skip loop=6mm,tip}];
    \chainin (p6)    [join];
    \chainin (e)     [join=by tip];
    \chainin (p7)    [join];
    { [start branch=plus]
      \chainin (plus)  [join=by {vh path,tip}];
      \chainin (p8)    [join=by {hv path,tip}];
    }
    { [start branch=minus]
      \chainin (minus) [join=by {vh path,tip}];
      \chainin (p8)    [join=by {hv path,tip}];
    }
    \chainin (p8)    [join];
    \chainin (ui2)   [join=by tip];
    \chainin (p9)    [join,join=with p6 by {skip loop=-11mm,tip}];
    \chainin (p10)   [join=by tip];
  }
\end{tikzpicture}
}\medskip

% Having read the previous tutorials, Ilka knows already how to set up the environment for her diagram, namely using a |tikzpicture| environment. She wonders which libraries she will need. She decides that she will postpone the decision and add the necessary libraries as needed as she constructs the picture.

阅读了前面的教程后，伊尔卡已经知道如何为她的图表配置环境，即使用 |tikzpicture| 环境。她想知道她将需要哪些库。 她决定推迟这个决定，并在创建图片时根据需要添加必要的库。


%\subsection{Styling the Nodes}
\subsection{为节点设置样式}

% The bulk of this tutorial will be about arranging the nodes and connecting them using chains, but let us start with setting up styles for the nodes.

本教程的大部分内容都是关于如何排列节点并使用链进行连接，让我们开始首先为节点设置样式。

% There are two kinds of nodes in the diagram, namely what theoreticians like to call \emph{terminals} and \emph{nonterminals}. For the terminals, Ilka decides to use a black color, which visually shows that ``nothing needs to be done about them''. The nonterminals, which still need to be ``processed'' further, get a bit of red mixed in.

图中有两种节点，即理论家喜欢称之为\emph{终端}和\emph{非终端}的节点。 对于终端节点，伊卡尔决定使用黑色，这从视觉上表明``无需进行任何操作''。 非终端节点则（仍需要进一步``处理''）混入了一些红色。

% Ilka starts with the simpler nonterminals, as there are no rounded corners involved. Naturally, she sets up a style:

伊卡尔从更简单的非终端节点开始，因为不涉及圆角。 自然地，她创建了一种风格：

%
\begin{codeexample}[preamble={\usetikzlibrary{positioning}}]
\begin{tikzpicture}[
    nonterminal/.style={
      % The shape:
      rectangle,
      % The size:
      minimum size=6mm,
      % The border:
      very thick,
      draw=red!50!black!50,         % 50% red and 50% black,
                                    % and that mixed with 50% white
      % The filling:
      top color=white,              % a shading that is white at the top...
      bottom color=red!50!black!20, % and something else at the bottom
      % Font
      font=\itshape
    }]
  \node [nonterminal] {unsigned integer};
\end{tikzpicture}
\end{codeexample}
%
% Ilka is pretty proud of the use of the |minimum size| option: As the name suggests, this option ensures that the node is at least 6mm by 6mm, but it will expand in size as necessary to accommodate longer text. By giving this option to all nodes, they will all have the same height of 6mm.

伊尔卡对 |minimum size| 选项的使用感到非常自豪。顾名思义，此选项可确保节点至少为6毫米 × 6毫米，但会根据需要扩展其大小以容纳更长的文本。 通过为所有节点提供此选项，它们都将具有相同的6毫米高度。

% Styling the terminals is a bit more difficult because of the round corners. Ilka has several options how she can achieve them. One way is to use the |rounded corners| option. It gets a dimension as parameter and causes all corners to be replaced by little arcs with the given dimension as radius. By setting the radius to 3mm, she will get exactly what she needs: circles, when the shapes are, indeed, exactly 6mm by 6mm and otherwise half circles on the sides:

由于圆角的缘故，对终端节点进行样式设置比较困难。伊尔卡有几种选择可以实现它们。 一种方法是使用 |rounded corners| 选项。 它以尺寸作为参数，并以指定尺寸作为半径的小圆弧替换所有角。 通过将半径设置为3毫米，如果节点形状正好为6毫米 × 6毫米时，她将得到一个完全满足她的需要的圆形，否则则节点的侧边为一半圆：

%
\begin{codeexample}[preamble={\usetikzlibrary{positioning}}]
\begin{tikzpicture}[node distance=5mm,
                    terminal/.style={
                      % The shape:
                      rectangle,minimum size=6mm,rounded corners=3mm,
                      % The rest
                      very thick,draw=black!50,
                      top color=white,bottom color=black!20,
                      font=\ttfamily}]
  \node (dot)   [terminal]                {.};
  \node (digit) [terminal,right=of dot]   {digit};
  \node (E)     [terminal,right=of digit] {E};
\end{tikzpicture}
\end{codeexample}

% Another possibility is to use a shape that is specially made for typesetting rectangles with arcs on the sides (she has to use the |shapes.misc| library to use it). This shape gives Ilka much more control over the appearance. For instance, she could have an arc only on the left side, but she will not need this.

另一种可能性是使用专门为排版矩形而在侧面带有弧线的形状（她必须使用 |shapes.misc| 库来创建这样的图形）。 这种形状使伊尔卡可以更好地控制外观。 例如，她可能只在左侧有一个弧，但她不需要这样做。

%
\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
\begin{tikzpicture}[node distance=5mm,
                    terminal/.style={
                      % The shape:
                      rounded rectangle,
                      minimum size=6mm,
                      % The rest
                      very thick,draw=black!50,
                      top color=white,bottom color=black!20,
                      font=\ttfamily}]
  \node (dot)   [terminal]                {.};
  \node (digit) [terminal,right=of dot]   {digit};
  \node (E)     [terminal,right=of digit] {E};
\end{tikzpicture}
\end{codeexample}
%
% At this point, she notices a problem. The baseline of the text in the nodes is not aligned:

在这一点上，她注意到一个问题。 节点中文本的基线未对齐：
%
\begin{codeexample}[setup code,hidden]
\tikzset{
  terminal/.style={
    % The shape:
    rounded rectangle,
    minimum size=6mm,
    % The rest
    very thick,draw=black!50,
    top color=white,bottom color=black!20,
    font=\ttfamily},
}
\end{codeexample}
%
\begin{codeexample}[preamble={\usetikzlibrary{calc,positioning,shapes.misc}}]
\begin{tikzpicture}[node distance=5mm]
  \node (dot)   [terminal]                {.};
  \node (digit) [terminal,right=of dot]   {digit};
  \node (E)     [terminal,right=of digit] {E};

  \draw [help lines] let \p1 = (dot.base),
                         \p2 = (digit.base),
                         \p3 = (E.base)
                     in (-.5,\y1) -- (3.5,\y1)
                        (-.5,\y2) -- (3.5,\y2)
                        (-.5,\y3) -- (3.5,\y3);
\end{tikzpicture}
\end{codeexample}
%
%\noindent (Ilka has moved the style definition to the preamble by saying |\tikzset{terminal/.style=...}|, so that she can use it in all pictures.)

\noindent （伊尔卡通过使用 |\tikzset{terminal/.style=...}| 将样式定义移到了序言中，以便她可以在所有图片中使用它。）

% For the |digit| and the |E| the difference in the baselines is almost imperceptible, but for the dot the problem is quite severe: It looks more like a multiplication dot than a period.

对于 |digit| 和 |E| 与基线之间的差异几乎是不可察觉的，但是对于点而言，问题非常严重：它看起来更像是一个乘法点而不是一个句点。

% Ilka toys with the idea of using the |base right=of...| option rather than |right=of...| to align the nodes in such a way that the baselines are all on the same line (the |base right| option places a node right of something so that the baseline is right of the baseline of the other object). However, this does not have the desired effect:

伊尔卡不是很认真地考虑使用 |base right=of...| 选项而不是 |right=of...|，以基线都在同一条线上的方式对齐节点（ |base right| 选项将节点放置在某个对象的右侧，以使基线位于另一个对象的基线的右侧）。 但是，并没有达到预期的效果：
%
\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
\begin{tikzpicture}[node distance=5mm]
  \node (dot)   [terminal]                     {.};
  \node (digit) [terminal,base right=of dot]   {digit};
  \node (E)     [terminal,base right=of digit] {E};
\end{tikzpicture}
\end{codeexample}
%
% The nodes suddenly ``dance around''! There is no hope of changing the position of text inside a node using anchors. Instead, Ilka must use a trick: The problem of mismatching baselines is caused by the fact that |.| and |digit| and |E| all have different heights and depth. If they all had the same, they would all be positioned vertically in the same manner. So, all Ilka needs to do is to use the |text height| and |text depth| options to explicitly specify a height and depth for the nodes.

节点突然在``跳舞''！使用锚点不可能改变节点内文本的位置。相反，伊尔卡必须使用一个技巧：基线不匹配的问题是由 |.|、|digit| 和 |E| 分别具有不同的高度和深度。如果它们的尺寸都是一样，它们将以相同的方式垂直放置。因此，卡尔所需要做的是使用 |text height| 和 |text depth| 选项显式地为节点指定高度和深度。

%
\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
\begin{tikzpicture}[node distance=5mm,
                    text height=1.5ex,text depth=.25ex]
  \node (dot)   [terminal]                {.};
  \node (digit) [terminal,right=of dot]   {digit};
  \node (E)     [terminal,right=of digit] {E};
\end{tikzpicture}
\end{codeexample}


% \subsection{Aligning the Nodes Using Positioning Options}
\subsection{使用定位选项对齐节点}

% Ilka now has the ``styling'' of the nodes ready. The next problem is to place them in the right places. There are several ways to do this. The most straightforward is to simply explicitly place the nodes at certain coordinates ``calculated by hand''. For very simple graphics this is perfectly alright, but it has several disadvantages:

伊尔卡现在已准备好节点的``样式''。 下一个问题是将它们放置在正确的位置。 有几种方法可以做到这一点。 最简单的方法是简单地将节点明确地放置在``手工计算''的特定坐标处。 对于非常简单的图形，这是完全可以的，但是它有几个缺点：

%
\begin{enumerate}
    % \item For more difficult graphics, the calculation may become complicated.
    \item 对于更复杂的图形，计算可能会变得非常复杂。
    % \item Changing the text of the nodes may make it necessary to recalculate the coordinates.
    \item 更改节点的文本可能需要重新计算坐标。
    % \item The source code of the graphic is not very clear since the relationships between the positions of the nodes are not made explicit.
    \item 图形的源代码不是很清楚，因为节点位置之间的关系没有明确。
\end{enumerate}

% For these reasons, Ilka decides to try out different ways of arranging the nodes on the page.

基于这些原因，伊尔卡决定尝试以其他方式在页面上排列节点。

% The first method is the use of \emph{positioning options}. To use them, you need to load the |positioning| library. This gives you access to advanced implementations of options like |above| or |left|, since you can now say |above=of some node| in order to place a node above of |some node|, with the borders separated by |node distance|.

第一种方法是使用\emph{定位选项}。要使用它们，您需要加载 |position| 库。这使您可以访问 |above| 或 |left| 之类的选项的高级实现，因为您现在可以使用 |above=of some node| 将一个节点放置在 |some node| 上方，其边界由 |node distance| 分隔开来。

% Ilka can use this to draw the place the nodes in a long row:

伊尔卡可以使用这个来绘制一个长排节点：

%
\begin{codeexample}[setup code,hidden]
\tikzset{
  nonterminal/.style={
    % The shape:
    rectangle,
    % The size:
    minimum size=6mm,
    % The border:
    very thick,
    draw=red!50!black!50,         % 50% red and 50% black,
                                  % and that mixed with 50% white
    % The filling:
    top color=white,              % a shading that is white at the top...
    bottom color=red!50!black!20, % and something else at the bottom
    % Font
    font=\itshape,
  },
}
\tikzset{
  terminal/.append style={text height=1.5ex,text depth=.25ex},
  nonterminal/.append style={text height=1.5ex,text depth=.25ex},
}
\end{codeexample}
%
\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
\begin{tikzpicture}[node distance=5mm and 5mm]
  \node (ui1)   [nonterminal]                     {unsigned integer};
  \node (dot)   [terminal,right=of ui1]           {.};
  \node (digit) [terminal,right=of dot]           {digit};
  \node (E)     [terminal,right=of digit]         {E};
  \node (plus)  [terminal,above right=of E]       {+};
  \node (minus) [terminal,below right=of E]       {-};
  \node (ui2)   [nonterminal,below right=of plus] {unsigned integer};
\end{tikzpicture}
\end{codeexample}

% For the plus and minus nodes, Ilka is a bit startled by their placements. Shouldn't they be more to the right? The reason they are placed in that manner is the following: The |north east| anchor of the |E| node lies at the ``upper start of the right arc'', which, a bit unfortunately in this case, happens to be the top of the node. Likewise, the |south west| anchor of the |+| node is actually at its bottom and, indeed, the horizontal and vertical distances between the top of the |E| node and the bottom of the |+| node are both 5mm.

对于加号和减号节点，伊尔卡对其放置位置感到有些惊讶。 他们不应该更右边吗？ 以这种方式放置它们的原因如下：|E| 节点的 |north east| 锚点位于``右圆弧的上起点''，在这种情况下，不幸的是，它恰好位于节点的顶部。 同样，|+| 节点的 |south west| 锚点实际上在其底部，实际上，|E| 节点顶部与 |+| 节点底部之间的水平和垂直距离均为5毫米。

% There are several ways of fixing this problem. The easiest way is to simply add a little bit of horizontal shift by hand:

有几种解决此问题的方法。 最简单的方法是简单地手动添加一点点水平移位：

%
\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
\begin{tikzpicture}[node distance=5mm and 5mm]
  \node (E)     [terminal]                                   {E};
  \node (plus)  [terminal,above right=of E,xshift=5mm]       {+};
  \node (minus) [terminal,below right=of E,xshift=5mm]       {-};
  \node (ui2)   [nonterminal,below right=of plus,xshift=5mm] {unsigned integer};
\end{tikzpicture}
\end{codeexample}

% A second way is to revert back to the idea of using a normal rectangle for the terminals, but with rounded corners. Since corner rounding does not affect anchors, she gets the following result:

第二种方法是回到使用标准矩形作为终端节点的想法，但是带有圆角。由于角的倒角不会影响锚点，她得到如下结果:

%
\begin{codeexample}[preamble={\usetikzlibrary{positioning,shapes.misc}}]
\begin{tikzpicture}[node distance=5mm and 5mm,terminal/.append style={rectangle,rounded corners=3mm}]
  \node (E)     [terminal]                        {E};
  \node (plus)  [terminal,above right=of E]       {+};
  \node (minus) [terminal,below right=of E]       {-};
  \node (ui2)   [nonterminal,below right=of plus] {unsigned integer};
\end{tikzpicture}
\end{codeexample}
%
% A third way is to use matrices, which we will do later.

第三种方法是使用矩阵，稍后我们将做。

% Now that the nodes have been placed, Ilka needs to add connections. Here, some connections are more difficult than others. Consider for instance the ``repeat'' line around the |digit|. One way of describing this line is to say ``it starts a little to the right of |digit| than goes down and then goes to the left and finally ends at a point a little to the left of |digit|''. Ilka can put this into code as follows:

现在已经放置了节点，伊尔卡需要添加连接。在这里，有些连接比其他连接更困难。例如，考虑 |digit| 周围的 ``循环''线。描述这条线的一种方式是，它从 |digit| 右边开始，然后往下，然后向左，最后在 |digit| 左边一点结束。伊尔卡可以将其放入代码如下:

%
\begin{codeexample}[preamble={\usetikzlibrary{calc,positioning,shapes.misc}}]
\begin{tikzpicture}[node distance=5mm and 5mm]
  \node (dot)   [terminal]                        {.};
  \node (digit) [terminal,right=of dot]           {digit};
  \node (E)     [terminal,right=of digit]         {E};

  \path (dot)   edge[->] (digit)  % simple edges
        (digit) edge[->] (E);

  \draw [->]
     % start right of digit.east, that is, at the point that is the
     % linear combination of digit.east and the vector (2mm,0pt). We
     % use the ($ ... $) notation for computing linear combinations
     ($ (digit.east) + (2mm,0) $)
     % Now go down
     -- ++(0,-.5)
     % And back to the left of digit.west
     -| ($ (digit.west) - (2mm,0) $);
\end{tikzpicture}
\end{codeexample}

% Since Ilka needs this ``go up/down then horizontally and then up/down to a target'' several times, it seems sensible to define a special \emph{to-path} for this. Whenever the |edge| command is used, it simply adds the current value of |to path| to the path. So, Ilka can set up a style that contains the correct path:

由于Ilka需要这样的``向上/向下，然后水平，然后向上/向下到目标''几次，似乎有必要为此定义一个特殊的\emph{to-path}。每当使用 |edge| 命令时，它只是将 |to path| 的当前值添加到路径中。因此，伊尔卡可以这样使用包含正确路径的样式：

%
\begin{codeexample}[preamble={\usetikzlibrary{calc,positioning,shapes.misc}}]
\begin{tikzpicture}[node distance=5mm and 5mm,
    skip loop/.style={to path={-- ++(0,-.5) -| (\tikztotarget)}}]
  \node (dot)   [terminal]                        {.};
  \node (digit) [terminal,right=of dot]           {digit};
  \node (E)     [terminal,right=of digit]         {E};

  \path (dot)   edge[->]           (digit)  % simple edges
        (digit) edge[->]           (E)
        ($ (digit.east) + (2mm,0) $)
                edge[->,skip loop] ($ (digit.west) - (2mm,0) $);
\end{tikzpicture}
\end{codeexample}

% Ilka can even go a step further and make her |skip loop| style parameterized. For this, the skip loop's vertical offset is passed as parameter |#1|. Also, in the following code Ilka specifies the start and targets differently, namely as the positions that are ``in the middle between the nodes''.

伊尔卡甚至可以更进一步，将她的 |skip loop| 样式参数化。为此，将 |skip loop| 的垂直偏移量作为参数 |#1| 传递。另外，在下面的代码中，伊尔卡以不同的方式指定了起点和目标，即``在节点中间''的位置。

%
\begin{codeexample}[preamble={\usetikzlibrary{calc,positioning,shapes.misc}}]
\begin{tikzpicture}[node distance=5mm and 5mm,
    skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}]
  \node (dot)   [terminal]                        {.};
  \node (digit) [terminal,right=of dot]           {digit};
  \node (E)     [terminal,right=of digit]         {E};

  \path (dot)   edge[->]                (digit)  % simple edges
        (digit) edge[->]                (E)
        ($ (digit.east)!.5!(E.west) $)
                edge[->,skip loop=-5mm] ($ (digit.west)!.5!(dot.east) $);
\end{tikzpicture}
\end{codeexample}


% \subsection{Aligning the Nodes Using Matrices}
\subsection{使用矩阵对齐节点}

% Ilka is still bothered a bit by the placement of the plus and minus nodes. Somehow, having to add an explicit |xshift| seems too much like cheating.

伊尔卡仍然对正负节点的放置感到困扰。 不知为什么，必须添加一个显式的 |xshift| 似乎似乎是一种耍小聪明。

% A perhaps better way of positioning the nodes is to use a \emph{matrix}. In \tikzname\ matrices can be used to align quite arbitrary graphical objects in rows and columns. The syntax is very similar to the use of arrays and tables in \TeX\ (indeed, internally \TeX\ tables are used, but a lot of stuff is going on additionally).

或许更好的定位节点的方法是使用\emph{矩阵}。在\tikzname\ 中，矩阵可用于对齐行和列中的任意图形对象。其语法非常类似于\TeX\ 中使用数组和表（实际上，在内部使用了\TeX\ 表，但还有很多其他内容）。

% In Ilka's graphic, there will be three rows: One row containing only the plus node, one row containing the main nodes and one row containing only the minus node.

在伊尔卡的图形中，矩阵将有三行：一行仅包含加号节点，一行包含主节点，另一行仅包含减号节点。

%
\begin{codeexample}[preamble={\usetikzlibrary{shapes.misc}}]
\begin{tikzpicture}
  \matrix[row sep=1mm,column sep=5mm] {
    % First row:
      & & & & \node [terminal] {+}; & \\
    % Second row:
    \node [nonterminal] {unsigned integer}; &
    \node [terminal]    {.};                &
    \node [terminal]    {digit};            &
    \node [terminal]    {E};                &
                                            &
    \node [nonterminal] {unsigned integer}; \\
    % Third row:
      & & & & \node [terminal] {-}; & \\
  };
\end{tikzpicture}
\end{codeexample}
%
% That was easy! By toying around with the row and columns separations, Ilka can achieve all sorts of pleasing arrangements of the nodes.  Ilka now faces the same connecting problem as before. This time, she has an idea: She adds small nodes (they will be turned into coordinates later on and be invisible) at all the places where she would like connections to start and end.

这好简单！通过摆弄行和列的分隔，伊尔卡可以实现各种令人愉快的节点安排。伊尔卡现在面临着和以前一样的连接问题。这一次，她有了一个想法：她在所有她希望连接开始和结束的地方添加小节点（它们稍后会变成坐标并且不可见）。

%
\begin{codeexample}[preamble={\usetikzlibrary{shapes.misc}}]
\begin{tikzpicture}[point/.style={circle,inner sep=0pt,minimum size=2pt,fill=red},
                   skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}}]
  \matrix[row sep=1mm,column sep=2mm] {
    % First row:
    & & & & & & &  & & & & \node (plus) [terminal] {+};\\
    % Second row:
    \node (p1) [point]  {}; &    \node (ui1)   [nonterminal] {unsigned integer}; &
    \node (p2) [point]  {}; &    \node (dot)   [terminal]    {.};                &
    \node (p3) [point]  {}; &    \node (digit) [terminal]    {digit};            &
    \node (p4) [point]  {}; &    \node (p5)    [point]  {};                      &
    \node (p6) [point]  {}; &    \node (e)     [terminal]    {E};                &
    \node (p7) [point]  {}; &                                                    &
    \node (p8) [point]  {}; &    \node (ui2)   [nonterminal] {unsigned integer}; &
    \node (p9) [point]  {}; &    \node (p10)   [point]       {};\\
    % Third row:
    & & & & & & &  & & & & \node (minus)[terminal] {-};\\
  };

  \path (p4) edge [->,skip loop=-5mm] (p3)
        (p2) edge [->,skip loop=5mm]  (p6);
\end{tikzpicture}
\end{codeexample}
%
% Now, it's only a small step to add all the missing edges.

现在，添加所有缺失的线段只是一小步。


% \subsection{The Diagram as a Graph}
\subsection{作为图形的图解}

% Matrices allow Ilka to align the nodes nicely, but the connections are not quite perfect. The problem is that the code does not really reflect the paths that underlie the diagram. For this, it seems natural enough to Ilka to use the |graphs| library since, after all, connecting nodes by edges is exactly what happens in a graph. The |graphs| library can both be used to connect nodes that have already been created, but it can also be used to create nodes ``on the fly'' and these processes can also be mixed.

矩阵允许伊尔卡很好地对齐节点，但是连接不是很完美。 问题在于该代码并没有真正反映该图的基础路径。 为此，伊尔卡似乎很自然地使用 |graphs| 库通过边连接节点，这正是图中发生的情况。|graphs| 库既可以用于连接已创建的节点，也可以用于``动态''创建节点，并且这些过程也可以混合使用。


% \subsubsection{Connecting Already Positioned Nodes}
\subsubsection{连接已经定位的节点}

% Ilka has already a fine method for positioning her nodes (using a |matrix|), so all that she needs is an easy way of specifying the edges. For this, she uses the |\graph| command (which is actually just a shorthand for |\path graph|). It allows her to write down edges between them in a simple way (the macro |\matrixcontent| contains exactly the matrix content from the previous example; no need to repeat it here):

伊尔卡已经有了一种很好的方法来定位她的节点（使用 |matrix|），所以她所需要的只是一种指定边的简单方法。为此，她使用 |\graph| 命令（实际上只是 |\path graph| 的简写）。该命令允许她以一种简单的方式写下节点之间的线段的代码（宏 |\matrixcontent| 正好包含了前面示例中的矩阵内容；这里不需要重复了）：

%
\begin{codeexample}[setup code,hidden]
\def\matrixcontent{
  % First row:
  \& \& \& \& \& \& \&  \& \& \& \& \node (plus) [terminal] {+};\\
  % Second row:
  \node (p1) [point]  {}; \&    \node (ui1)   [nonterminal] {unsigned integer}; \&
  \node (p2) [point]  {}; \&    \node (dot)   [terminal]    {.};                \&
  \node (p3) [point]  {}; \&    \node (digit) [terminal]    {digit};            \&
  \node (p4) [point]  {}; \&    \node (p5)    [point]  {};                      \&
  \node (p6) [point]  {}; \&    \node (e)     [terminal]    {E};                \&
  \node (p7) [point]  {}; \&                                                    \&
  \node (p8) [point]  {}; \&    \node (ui2)   [nonterminal] {unsigned integer}; \&
  \node (p9) [point]  {}; \&    \node (p10)   [point]       {};\\
  % Third row:
  \& \& \& \& \& \& \&  \& \& \& \& \node (minus)[terminal] {-};\\
}
\end{codeexample}
%
\begin{codeexample}[
    preamble={\usetikzlibrary{graphs,shapes.misc}},
    pre={\tikzset{ampersand replacement=\&,point/.style={coordinate}}},
]
\begin{tikzpicture}[skip loop/.style={to path={-- ++(0,#1) -| (\tikztotarget)}},
                    hv path/.style={to path={-| (\tikztotarget)}},
                    vh path/.style={to path={|- (\tikztotarget)}}]
  \matrix[row sep=1mm,column sep=2mm] { \matrixcontent };

  \graph {
    (p1) -> (ui1) -- (p2) -> (dot) -- (p3) -> (digit) -- (p4)
         -- (p5)  -- (p6) -> (e) -- (p7) -- (p8) -> (ui2) -- (p9) -> (p10);
    (p4) ->[skip loop=-5mm]  (p3);
    (p2) ->[skip loop=5mm]   (p5);
    (p6) ->[skip loop=-11mm] (p9);
    (p7) ->[vh path]         (plus)  -> [hv path] (p8);
    (p7) ->[vh path]         (minus) -> [hv path] (p8);
  };
\end{tikzpicture}
\end{codeexample}

% This is already pretty near to the desired result, just a few ``finishing touches'' are needed to style the edges more nicely.

这已经很接近预期的结果了，只需要几次``修饰''就可以更好地对线段进行样式化。

% However, Ilka does not have the feeling that the |graph| command is all that hot in the example. It certainly does cut down on the number of characters she has to write, but the overall graph structure is not that much clear -- it is still mainly a list of paths through the graph. It would be nice to specify that, say, there the path from |(p7)| sort of splits to |(plus)| and |(minus)| and then merges once more at |(p8)|. Also, all these parentheses are bit hard to type.

然而，伊尔卡并不认为示例中的 |graph| 命令有那么的优美。这当然减少了她所需要写的字符的数量，但是总体的图结构并不是那么清晰——它仍然主要是图形的一些路径列表。把它具体化会很好，比如将 |(p7)| 路径分割为 |(+)| 和 |(-)| 然后再合并到 |(p8)|。而且，所有的这些括号都很难键入。

% It turns out that edges from a node to a whole group of nodes are quite easy to specify, as shown in the next example. Additionally, by using the |use existing nodes| option, Ilka can also leave out all the parentheses (again, some options have been moved outside to keep the examples shorter):

事实证明，从一个节点到整个节点组的边非常容易指定，如下例所示。 另外，通过使用 |use existing nodes| 选项，伊尔卡还可以省略所有括号（此外，一些选项已移到外面，以使示例更短）：

%
\begin{codeexample}[
    preamble={\usetikzlibrary{arrows.meta,graphs,shapes.misc}},
    pre={\tikzset{
    ampersand replacement=\&,
    point/.style={coordinate},
    skip loop/.style={to path={-- ++(0,##1) -| (\tikztotarget)}},
    hv path/.style={to path={-| (\tikztotarget)}},
    vh path/.style={to path={|- (\tikztotarget)}},
}},
]
\begin{tikzpicture}[>={Stealth[round]},thick,black!50,text=black,
                    every new ->/.style={shorten >=1pt},
                    graphs/every graph/.style={edges=rounded corners}]
  \matrix[column sep=4mm] { \matrixcontent };

  \graph [use existing nodes] {
    p1 -> ui1 -- p2 -> dot -- p3 -> digit -- p4 -- p5  -- p6 -> e -- p7 -- p8 -> ui2 -- p9 -> p10;
    p4 ->[skip loop=-5mm]  p3;
    p2 ->[skip loop=5mm]   p5;
    p6 ->[skip loop=-11mm] p9;
    p7 ->[vh path] { plus, minus } -> [hv path] p8;
  };
\end{tikzpicture}
\end{codeexample}


% \subsubsection{Creating Nodes Using the Graph Command}
\subsubsection{使用Graph命令创建节点}

% Ilka has heard that the |graph| command is also supposed to make it easy to create nodes, not only to connect them. This is, indeed, correct: When the |use existing nodes| option is not used and when a node name is not surrounded by parentheses, then \tikzname\ will actually create a node whose name and text is the node name:

伊尔卡听说 |graph| 命令还可以使创建节点变得更容易，不仅仅是连接它们。 确实，这是正确的：如果没有使用|use existing nodes|选项，并且节点名没有被括号括起来，那么\tikzname\ 将实际创建一个节点，其名称和文本为节点名：

%
\begin{codeexample}[preamble={\usetikzlibrary{graphs}}]
\tikz \graph [grow right=2cm] { unsigned integer -> d -> digit -> E };
\end{codeexample}
%
% Not quite perfect, but we are getting somewhere. First, let us change the positioning algorithm by saying |grow right sep|, which causes new nodes to be placed to the right of the previous nodes with a certain fixed separation (|1em| by default). Second, we add some options to make the node ``look nice''. Third, note the funny |d| node above: Ilka tried writing just |.| there first, but got some error messages. The reason is that a node cannot be called |.| in \tikzname, so she had to choose a different name -- which is not good, since she wants a dot to be shown! The trick is to put the dot in quotation marks, this allows you to use ``quite arbitrary text'' as a node name:

这并不太完美，但我们正在取得一些进展。首先，通过使用 |grow right sep|，我们可以改变定位算法，，这将导致新节点以一定的固定间隔放置在前一个节点的右侧（默认为 |1em|）。其次，我们添加了一些选项使节点看起来更漂亮。第三，注意上面有趣的 |d| 节点：伊尔卡尝试使用 |.|，但有一些错误消息。原因是在\tikzname 中节点不能被称为|.|，所以她必须选择一个不同的名字——这是不好的，因为她想要一个点显示！诀窍是把点放在引号中，这允许你使用``相当随意的文本''作为节点名：

%
\begin{codeexample}[preamble={\usetikzlibrary{graphs,shapes.misc}}]
\tikz \graph [grow right sep] {
  unsigned integer[nonterminal] -> "."[terminal] -> digit[terminal] -> E[terminal]
};
\end{codeexample}
%
% Now comes the fork to the plus and minus signs. Here, Ilka can use the grouping mechanism of the |graph| command to create a split:

现在轮到正号和负号了。在这里，伊尔卡可以使用 |graph| 命令的分组机制来创建节点的分裂：

%
\begin{codeexample}[preamble={\usetikzlibrary{graphs,shapes.misc}}]
\tikz \graph [grow right sep] {
  unsigned integer  [nonterminal] ->
  "."               [terminal] ->
  digit             [terminal] ->
  E                 [terminal] ->
  {
    "+"             [terminal],
    ""              [coordinate],
    "-"             [terminal]
  } ->
  ui2/unsigned integer [nonterminal]
};
\end{codeexample}
%
% Let us see, what is happening here. We want two |unsigned integer| nodes, but if we just were to use this text twice, then \tikzname\ would have noticed that the same name was used already in the current graph and, being smart (actually too smart in this case), would have created an edge back to the already-created node. Thus, a fresh name is needed here. However, Ilka also cannot just write |unsigned integer2|, because she wants the original text to be shown, after all! The trick is to use a slash inside the node name: In order to ``render'' the node, the text following the slash is used instead of the node name, which is the text before the slash. Alternatively, the |as| option can be used, which also allows you to specify how a node should be rendered.

让我们看看，这里发生了什么。我们想要两个 |unsigned integer| 节点，但是如果我们只是使用这个文本两次，那么\tikzname\ 已经注意到在当前图使用了相同的名称，这看起来很智能的样子（实际上在这种情况下并不太智能），就会创建一条回到已经创建的节点的边。因此，这里需要一个新的名称。但是伊尔卡也不能就写 |unsigned integer2|，毕竟她想要显示原始文本！诀窍是在节点名中使用斜杠：为了``呈现''节点，使用斜杠后面的文本，而不是节点名，节点名是斜杠前面的文本。另外，也可以使用 |as| 选项，它也允许您指定应该如何呈现节点。

% It turns out that Ilka does not need to invent a name like |ui2| for a node that she will not reference again anyway. In this case, she can just leave out the name (write nothing before |/|), which always stands for a ``fresh, anonymous'' node name.

事实证明，伊尔卡不需要发明 |ui2| 之类的名称。 对于她来说，她不会再次引用这个节点。 在这种情况下，她可以省略节点名（在|/|之前不写任何内容），该名称始终代表``新的，匿名的''节点名称。

% Next, Ilka needs to add some coordinates in between of some nodes where the back-loops should got and she needs to shift the nodes a bit:

接下来，伊尔卡需要在反循环包含的一些节点上增加一些坐标，她需要对节点进行一些移动：

%
\begin{codeexample}[
    preamble={\usetikzlibrary{arrows.meta,graphs,shapes.misc}},
    pre={\tikzset{
    skip loop/.style={to path={-- ++(0,##1) -| (\tikztotarget)}},
    hv path/.style={to path={-| (\tikztotarget)}},
    vh path/.style={to path={|- (\tikztotarget)}},
}},
]
\begin{tikzpicture}[>={Stealth[round]}, thick, black!50, text=black,
                    every new ->/.style={shorten >=1pt},
                    graphs/every graph/.style={edges=rounded corners}]
  \graph [grow right sep, branch down=7mm] {
    /                  [coordinate] ->
    unsigned integer   [nonterminal] --
    p1                 [coordinate] ->
    "."                [terminal] --
    p2                 [coordinate] ->
    digit              [terminal] --
    p3                 [coordinate] --
    p4                 [coordinate] --
    p5                 [coordinate] ->
    E                  [terminal] --
    q1                 [coordinate] ->[vh path]
    { [nodes={yshift=7mm}]
      "+"                [terminal],
      q2/                [coordinate],
      "-"                [terminal]
    } -> [hv path]
    q3                 [coordinate] --
    /unsigned integer  [nonterminal] --
    p6                 [coordinate] ->
    /                  [coordinate];

    p1 ->[skip loop=5mm]   p4;
    p3 ->[skip loop=-5mm]  p2;
    p5 ->[skip loop=-11mm] p6;
  };
\end{tikzpicture}
\end{codeexample}

% All that remains to be done is to somehow get rid of the strange curves between the |E| and the unsigned integer. They are caused by \tikzname's attempt at creating an edge that first goes vertical and then horizontal but is actually just horizontal. Additionally, the edge should not really be pointed; but it seems difficult to get rid of this since the \emph{other} edges from |q1|, namely to |plus| and |minus| should be pointed.

剩下要做的就是以某种方式摆脱 |E| 和unsigned integer之间的奇怪曲线。它们是由于\tikzname 试图创造一个先垂直后水平前进的边引起的，但实际上只是水平前进的边。 另外，实际上箭头不应指向边；但是似乎很难摆脱这一点，因为来自 |q1| 的其他边，即 |plus| 和 |minus|，应该被指向。

% It turns out that there is a nice way of solving this problem: You can specify that a graph is |simple|. This means that there can be at most one edge between any two nodes. Now, if you specify an edge twice, the options of the second specification ``win''. Thus, by adding two more lines that ``correct'' these edges, we get the final diagram with its complete code:

事实证明，有一个解决此问题的好方法：您可以指定图是 |simple| 的。 这意味着任何两个节点之间最多可以有一条边。 现在，如果您指定两次边，则第二个的选项为``赢得胜利''。 因此，通过多添加两条线来``校正''这些边，我们得到了带有完整代码的最终图：

%
\begin{codeexample}[preamble={\usetikzlibrary{arrows.meta,graphs,shapes.misc}}]
\tikz [>={Stealth[round]}, black!50, text=black, thick,
       every new ->/.style          = {shorten >=1pt},
       graphs/every graph/.style    = {edges=rounded corners},
       skip loop/.style             = {to path={-- ++(0,#1) -| (\tikztotarget)}},
       hv path/.style               = {to path={-| (\tikztotarget)}},
       vh path/.style               = {to path={|- (\tikztotarget)}},
       nonterminal/.style           = {
         rectangle, minimum size=6mm, very thick, draw=red!50!black!50, top color=white,
         bottom color=red!50!black!20, font=\itshape, text height=1.5ex,text depth=.25ex},
       terminal/.style              = {
         rounded rectangle,  minimum size=6mm, very thick, draw=black!50, top color=white,
         bottom color=black!20, font=\ttfamily, text height=1.5ex, text depth=.25ex},
       shape                        = coordinate
       ]
  \graph [grow right sep, branch down=7mm, simple] {
    / -> unsigned integer[nonterminal] -- p1 -> "." [terminal] -- p2 -> digit[terminal] --
    p3 -- p4 -- p5 -> E[terminal] -- q1 ->[vh path]
    {[nodes={yshift=7mm}]
      "+"[terminal], q2, "-"[terminal]
    } -> [hv path]
    q3 -- /unsigned integer [nonterminal] -- p6 -> /;

    p1 ->[skip loop=5mm]   p4;
    p3 ->[skip loop=-5mm]  p2;
    p5 ->[skip loop=-11mm] p6;

    q1 -- q2 -- q3;  % make these edges plain
  };
\end{codeexample}




%% TODOsp: a commented subsection
% \subsection{Using Chains}
%
% Matrices allow Ilka to align the nodes nicely, but the connections are
% not quite perfect. The problem is that the code does not really
% reflect the paths that underlie the diagram.
%
%
% For this reason, Ilka decides to try out \emph{chains} by including
% the |chain| library. Basically, a chain is just a sequence of
% (usually) connected nodes. The nodes can already have been constructed
% or they can be constructed as the chain is constructed (or these
% processes can be mixed).
%
% \subsubsection{Creating a Simple Chain}
%
%
% Ilka starts with creating a chain from scratch. For this, she starts a
% chain using the |start chain| option in a scope. Then, inside the
% scope, she uses the |on chain| option on nodes to add them to the
% chain.
% \begin{codeexample}[]
% \begin{tikzpicture}[start chain,node distance=5mm]
%   \node [on chain,nonterminal]  {unsigned integer};
%   \node [on chain,terminal]     {.};
%   \node [on chain,terminal]     {digit};
%   \node [on chain,terminal]     {E};
%   \node [on chain,nonterminal]  {unsigned integer};
% \end{tikzpicture}
% \end{codeexample}
% (Ilka will add the plus and minus nodes later.)
%
% As can be seen, the nodes of a chain are placed in a row. This can be
% changed, for instance by saying |start chain=going below| we get a
% chain where each node is below the previous one.
%
% The next step is to \emph{join} the nodes of the chain. For this, we
% add the |join| option to each node. This joins the node with the
% previous node (for the first node nothing happens).
% \begin{codeexample}[]
% \begin{tikzpicture}[start chain,node distance=5mm]
%   \node [on chain,join,nonterminal]  {unsigned integer};
%   \node [on chain,join,terminal]     {.};
%   \node [on chain,join,terminal]     {digit};
%   \node [on chain,join,terminal]     {E};
%   \node [on chain,join,nonterminal]  {unsigned integer};
% \end{tikzpicture}
% \end{codeexample}
% In order to get a arrow tip, we redefine the |every join| style. Also,
% we move the |join| and |on chain| options to the |every node|
% style so that we do not have to repeat them so often.
% \begin{codeexample}[]
% \begin{tikzpicture}[start chain,node distance=5mm, every node/.style={on chain,join}, every join/.style={->}]
%   \node [nonterminal]  {unsigned integer};
%   \node [terminal]     {.};
%   \node [terminal]     {digit};
%   \node [terminal]     {E};
%   \node [nonterminal]  {unsigned integer};
% \end{tikzpicture}
% \end{codeexample}
%
%
% \subsubsection{Branching and Joining a Chain}
%
% It is now time to add the plus and minus signs. They obviously
% \emph{branch off} the main chain. For this reason, we start a branch
% for them using the |start branch| option.
% \begin{codeexample}[]
% \begin{tikzpicture}[start chain,node distance=5mm, every node/.style={on chain,join}, every join/.style={->}]
%   \node [nonterminal]  {unsigned integer};
%   \node [terminal]     {.};
%   \node [terminal]     {digit};
%   \node [terminal]     {E};
%   \begin{scope}[start branch=plus]
%     \node (plus)  [terminal,on chain=going above right] {+};
%   \end{scope}
%   \begin{scope}[start branch=minus]
%     \node (minus) [terminal,on chain=going below right] {-};
%   \end{scope}
%   \node [nonterminal,join=with plus,join=with minus]  {unsigned integer};
% \end{tikzpicture}
% \end{codeexample}
%
% Let us see, what is going on here. First, the |start branch| begins a
% branch, starting with the node last created on the current chain,
% which is the |E| node in our case. This is implicitly also the first
% node on this branch. A branch is nothing different from a chain, which
% is why the plus node is put on this branch using the |on chain|
% option. However, this time we specify the placement of the node
% explicitly using |going |\meta{direction}. This causes the plus sign
% to be placed above and right of the |E| node. It is automatically
% joined to its predecessor on the branch by the implicit |join|
% option.
%
% When the first branch ends, only the plus node has been added and the
% current chain is the original chain once more and we are back to the
% |E| node. Now we start a new branch for the minus node. After this
% branch, the current chain ends at |E| node once more.
%
% Finally, the rightmost unsigned integer is added to the (main) chain,
% which is why it is joined correctly with the |E| node. The two
% additional |join| options get a special |with| parameter. This allows
% you to join a node with a node other than the predecessor on the
% chain. The  |with| should be followed by the name of a node.
%
% Since Ilka will need scopes more often in the following, she includes
% the |scopes| library. This allows her to replace |\begin{scope}|
%   simply by an opening brace and  |\end{scope}| by the corresponding
% closing brace. Also, in the following example we reference
% the nodes |plus| and |minus| using
% their automatic name: The $i$th node on a chain is called
% |chain-|\meta{i}. For a branch \meta{branch}, the $i$th node is called
% |chain/|\meta{branch}|-|\meta{i}. The \meta{i} can be replaced by
% |begin| and |end| to reference the first and (currently) last node on
% the chain.
%
% \begin{codeexample}[]
% \begin{tikzpicture}[start chain,node distance=5mm, every on chain/.style={join}, every join/.style={->}]
%   \node [on chain,nonterminal]  {unsigned integer};
%   \node [on chain,terminal]     {.};
%   \node [on chain,terminal]     {digit};
%   \node [on chain,terminal]     {E};
%   { [start branch=plus]
%     \node (plus)  [terminal,on chain=going above right] {+};
%   }
%   { [start branch=minus]
%     \node (minus) [terminal,on chain=going below right] {-};
%   }
%   \node [nonterminal,on chain,join=with chain/plus-end,join=with chain/minus-end]  {unsigned integer};
% \end{tikzpicture}
% \end{codeexample}
%
%
% The next step is to add intermediate coordinate nodes in the same
% manner as Ilka did for the matrix. For them, we change the |join|
% style slightly, namely for these nodes we do not want an arrow
% tip. This can be achieved either by (locally) changing the
% |every join| style or, which is what is done in the below example, by
% giving the desired style using |join=by ...|, where |...| is the style
% to be used for the join.
%
% \begin{codeexample}[]
% \begin{tikzpicture}[start chain,node distance=5mm and 2mm,
%                     every node/.style={on chain},
%                     nonterminal/.append style={join=by ->},
%                     terminal/.append style={join=by ->},
%                     point/.style={join=by -,circle,fill=red,minimum size=2pt,inner sep=0pt}]
%   \node [point] {};  \node [nonterminal] {unsigned integer};
%   \node [point] {};  \node [terminal]    {.};
%   \node [point] {};  \node [terminal]    {digit};
%   \node [point] {};  \node [point]       {};
%   \node [point] {};  \node [terminal]    {E};
%   \node [point] {};
%   { [node distance=5mm and 1cm] % local change in horizontal distance
%     { [start branch=plus]
%       \node (plus)  [terminal,on chain=going above right] {+};
%     }
%     { [start branch=minus]
%       \node (minus) [terminal,on chain=going below right] {-};
%     }
%     \node [point,below right=of plus,join=with chain/plus-end by ->,join=with chain/minus-end by ->] {};
%   }
%   \node [nonterminal] {unsigned integer};
%   \node [point]       {};
% \end{tikzpicture}
% \end{codeexample}
%
%
% \subsubsection{Chaining Together Already Positioned Nodes}
%
% The final step is to add the missing arrows. We can also use branches
% for them (even though we do not have to, but it is good practice and
% they exhibit the structure of the diagram in the code).
%
% Let us start with the repeat loop around the |digit|. This can be
% thought of as a branch that starts at the point after the digit and
% that ends at the point before the digit. However, we have already
% constructed the point before the digit! In such cases, it is possible
% to ``chain in'' an already positioned node, using the |\chainin|
% command. This command must be followed by a coordinate that contains a
% node name and optionally some options. The effect is that the named
% node is made part of the current chain.
%
% \begin{codeexample}[pre={\tikzset{node distance=5mm and 2mm,
%                     every node/.style={on chain},
%                     terminal/.append style={join=by ->},
%                     point/.style={join=by -,circle,fill=red,minimum size=2pt,inner sep=0pt}}}]
% \begin{tikzpicture}[start chain] % plus some styles that are not shown
%   \node                [point] {};
%   \node (before digit) [point] {};
%   \node                [terminal]    {digit};
%   \node                [point] {};
%   { [start branch=digit loop]
%     \chainin (before digit) [join=by {->,skip loop=-5mm}];
%   }
%   \node                [point] {};
% \end{tikzpicture}
% \end{codeexample}
%
%
% \subsubsection{Combined Use of Matrices and Chains}
%
% Ilka's final idea is to combine matrices and chains in the following
% manner: She will use a matrix to position the nodes. However, to show
% the logical ``flow structure'' inside the diagram, she will create
% chains and branches that show what is going on.
%
% Ilka starts with the matrix we had earlier, only with slightly adapted
% styles. Then she writes down the main chain and its branches:
%
% \begin{codeexample}[preamble={\usetikzlibrary{arrows.meta}}]
% \begin{tikzpicture}[point/.style={coordinate},>={Stealth[round]},thick,draw=black!50,
%                     tip/.style={->,shorten >=1pt},every join/.style={rounded corners},
%                     hv path/.style={to path={-| (\tikztotarget)}},
%                     vh path/.style={to path={|- (\tikztotarget)}}]
%   \matrix[column sep=4mm] {
%     % First row:
%     & & & & & & &  & & & & \node (plus) [terminal] {+};\\
%     % Second row:
%     \node (p1) [point]  {}; &    \node (ui1)   [nonterminal] {unsigned integer}; &
%     \node (p2) [point]  {}; &    \node (dot)   [terminal]    {.};                &
%     \node (p3) [point]  {}; &    \node (digit) [terminal]    {digit};            &
%     \node (p4) [point]  {}; &    \node (p5)    [point]  {};                      &
%     \node (p6) [point]  {}; &    \node (e)     [terminal]    {E};                &
%     \node (p7) [point]  {}; &                                                    &
%     \node (p8) [point]  {}; &    \node (ui2)   [nonterminal] {unsigned integer}; &
%     \node (p9) [point]  {}; &    \node (p10)   [point]       {};\\
%     % Third row:
%     & & & & & & &  & & & & \node (minus)[terminal] {-};\\
%   };
%
%   { [start chain]
%     \chainin (p1);
%     \chainin (ui1)   [join=by tip];
%     \chainin (p2)    [join];
%     \chainin (dot)   [join=by tip];
%     \chainin (p3)    [join];
%     \chainin (digit) [join=by tip];
%     \chainin (p4)    [join];
%     { [start branch=digit loop]
%       \chainin (p3) [join=by {skip loop=-6mm,tip}];
%     }
%     \chainin (p5)    [join,join=with p2 by {skip loop=6mm,tip}];
%     \chainin (p6)    [join];
%     \chainin (e)     [join=by tip];
%     \chainin (p7)    [join];
%     { [start branch=plus]
%       \chainin (plus)  [join=by {vh path,tip}];
%       \chainin (p8)    [join=by {hv path,tip}];
%     }
%     { [start branch=minus]
%       \chainin (minus) [join=by {vh path,tip}];
%       \chainin (p8)    [join=by {hv path,tip}];
%     }
%     \chainin (p8)    [join];
%     \chainin (ui2)   [join=by tip];
%     \chainin (p9)    [join,join=with p6 by {skip loop=-11mm,tip}];
%     \chainin (p10)   [join=by tip];
%   }
% \end{tikzpicture}
% \end{codeexample}
